﻿//  -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Documents
//  File name:	LookupFieldWithPickerControl.cs
//  Developer:	Solomatov Igor
//  Created:	16.04.2012
// 
//  -------------------- iSharePoint -------------------- //

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Smart.Common;
using Smart.Common.Entities;

// ReSharper disable CheckNamespace

namespace Smart.Documents.Fields.LookupFieldWithPicker
// ReSharper restore CheckNamespace
{
	public class LookupFieldWithPickerControl : BaseFieldControl
	{
		protected LookupFieldWithPickerEntityEditor lookupEditor;

		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);

			if (ControlMode == SPControlMode.New && !Page.IsPostBack)
				SetFieldControlValue(null);
		}

		public override object Value
		{
			get
			{
				EnsureChildControls();

				var resolvedEntities = lookupEditor.ResolvedEntities;
				if (resolvedEntities.Count == 0)
					return null;

				if (resolvedEntities.Count != 1)
					throw new IndexOutOfRangeException();

				var entity = (PickerEntity)resolvedEntities[0];

				return new SPFieldLookupValue(int.Parse(entity.Key), entity.DisplayText);
			}
			set
			{
				EnsureChildControls();
				SetFieldControlValue(value);
			}
		}

		protected override void CreateChildControls()
		{
			var lookupFieldPicker = (LookupFieldWithPicker)Field;

			using (var lookupWeb = Web.Site.OpenWeb(lookupFieldPicker.LookupWebId))
			{
				var lookupList = lookupWeb.Lists[new Guid(lookupFieldPicker.LookupList)];

				SPField lookupField;

				try
				{
					lookupField = lookupList.Fields.GetFieldByInternalName(lookupFieldPicker.LookupField);
				}
				catch
				{
					//field has been deleted, fallback is the id field
					//lookupWeb = Web.Site.OpenWeb(lookupFieldPicker.LookupWebId);
					lookupField = lookupList.Fields[SPBuiltInFieldId.ID];

					using (new UnsafeUpdate(List.ParentWeb))
					{
						lookupFieldPicker = (LookupFieldWithPicker)List.Fields[Field.Id];
						lookupFieldPicker.LookupField = lookupField.InternalName;
						lookupFieldPicker.Update(true);
					}
				}

				lookupEditor = new LookupFieldWithPickerEntityEditor
								{
									CssClass = "ms-usereditor",
									AllowTypeIn =
										lookupFieldPicker.SearchQuery.IsNullOrEmpty() ||
										(!lookupFieldPicker.SearchQuery.Contains(Common.Const.Template.TagSymbol) &&
										 !lookupFieldPicker.SearchQuery.Contains(Common.Const.Template.TagSymbol2)),
									CustomProperty =
										new LookupFieldWithPickerPropertyBag(lookupFieldPicker.LookupWebId,
																			 lookupList.ID,
																			 lookupField.Id,
																			 lookupFieldPicker.SearchableFields,
																			 lookupFieldPicker.MaxSearchResults,
																			 lookupFieldPicker.EntityEditorRows,
																			 Item.ID,
																			 Field.InternalName,
																			 FormatSearchQuery(lookupFieldPicker.SearchQuery)).ToString(),
									MultiSelect = lookupFieldPicker.AllowMultipleValues
								};
			}

			Controls.Add(lookupEditor);

			base.CreateChildControls();
		}

		private string FormatSearchQuery(string searchQuery)
		{
			var listItem = Item as SPListItem;

			if (listItem == null)
				return searchQuery;

			var culture =
				Web != null
					? Web.UICulture
					: System.Threading.Thread.CurrentThread.CurrentUICulture;

			var fv = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);

			listItem.GetValues(fv);

			var uv = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);

			fv.GetUserValues(uv, culture);

			return
				searchQuery.ReplaceTags(uv, Smart.Common.Const.Template.TagSymbol);
		}

		private void SetFieldControlValue(object value)
		{
			lookupEditor.Entities.Clear();

			var list = new ArrayList();

			var lookupFieldPicker = (LookupFieldWithPicker)Field;

			if (ControlMode == SPControlMode.New && lookupEditor.Entities.Count == 0)
			{
				var strValue = ParseDefaultValue(lookupFieldPicker.CustomDefaultValue);

				if (strValue == null)
					return;

				var defaultEntity = lookupEditor.ValidateEntity(new PickerEntity { Key = strValue, DisplayText = strValue });

				if (defaultEntity != null)
					list.Add(defaultEntity);
			}
			else
			{
				if (value == null || value.ToString() == "")
					return;

				var lookupValue = value as SPFieldLookupValue;

				var entity = lookupEditor.GetEntityById(lookupValue.LookupId);

				if (entity != null)
				{
					list.Add(entity);
				}
			}

			lookupEditor.UpdateEntities(list);
		}

		protected string ParseDefaultValue(object value)
		{
			var strValue = (string)value;

			if (strValue == "[CurrentUserId]")
			{
				strValue = Web.CurrentUser.ID.ToString();
			}
			else
			{
				if (String.IsNullOrEmpty(strValue))
				{
					strValue = Context.Request.QueryString[Field.InternalName];
				}
				else
				{
					var m = Regex.Match(strValue, @"^\[UrlParam:(\w+)\]");

					if (m.Success)
					{
						strValue = Context.Request.QueryString[m.Groups[1].Value];
					}
				}
			}

			return strValue;
		}

		public override void Validate()
		{
			if (ControlMode == SPControlMode.Display)
				return;

			EnsureChildControls();

			base.Validate();

			var val = Value;

			if (!IsValid || val != null)
				return;

			if (!Field.Required)
				return;

			IsValid = false;
			ErrorMessage = SPResource.GetString("MissingRequiredField", new object[0]);
		}
	}
}